package com.yvon.service.demo.jdk.function;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * @author : Yvon
 * @since : 2021-09-26
 */
public class UserFilter <T> {
    public static <T>List<T> filter(List<T> list, BooleanFunctionalInterface b) {
        if (list == null || list.isEmpty()) {
            return new ArrayList<>(0);
        }

        List<T> result = new ArrayList<>(list.size());
        for (int i = 0; i < list.size(); i ++ ) {
            T t = list.get(i);
            if (b.test(t)) {
                result.add(t);
            }
        }
        return result;
    }

    /**
     * Predicate<T> 接口
     *
     * <pre>
     *     定义了一个支持泛型的boolean test( T)的抽象方法，其函数描述符为 （T）-> boolean
     *     返回boolean
     * </pre>
     *
     * @param list      列表
     * @param predicate 谓词
     * @return List<T>
     * @author : Yvon / 2021-09-26
     */
    public static <T> List<T> predicate(List<T> list, Predicate predicate) {
        if (list == null || list.isEmpty()) {
            return new ArrayList<>(0);
        }

        List<T> result = new ArrayList<>(list.size());
        for (int i = 0; i < list.size(); i ++ ) {
            T t = list.get(i);
            if (predicate.test(t)) {
                result.add(t);
            }
        }
        return result;
    }


    /**
     * Consumer<T>接口
     *
     * <pre>
     *     定义了一个void accept(T)的抽象方法,操作某一对象，但无需返回的的函数式接口
     * </pre>
     *
     * @param list     列表
     * @param consumer 消费者
     * @return List<T>
     * @author : Yvon / 2021-09-26
     */
    public static <T> void consumer(List<T> list, Consumer consumer) {
        if (list == null || list.isEmpty()) {
            return;
        }
        List<T> result = new ArrayList<>(list.size());
        for(int i=0; i<list.size(); i++){
            T t = list.get(i);
            consumer.accept(t);
        }
    }

    public static <T> List<T> listFactory(int count, Supplier<T> supplier) {
        List<T> result = new ArrayList<>();
        for (int i = 0; i < count; i ++ ) {
            T t = supplier.get();
            result.add(t);
        }

        return result;
    }

    public static <T> List<String> function(List<T> list, Function<T, String> function) {
        if (list == null || list.isEmpty()) {
            return new ArrayList<>(0);
        }


        List<String> result = new ArrayList<>(list.size());
        for (int i = 0; i < list.size(); i ++ ) {
            T t = list.get(i);
            String apply = function.apply(t);
            result.add(apply);
        }
        return result;
    }
}
